/* 
 * File:   IRHandler.cpp
 * Author: Dylan
 * 
 * Created on 15 juni 2012, 12:19
 */

#include "IRHandler.h"

IRState state = Waiting;
IRSignal shooter;
int signalCounter, indexCounter = 0, bits[15], lowCounter = 0;

void IRHandler::main(void) {
    std::cout << "\n Ir starting\n";
    for (;;) {
        switch (state) {
            case Waiting:
                //std::cout << "Entered waiting state\n";
                waiting();
                break;
            case Receiving:
                //std::cout << "Entered receiving state\n";
                receiving();
                break;

            case Idle:
                std::cout << "Entered idle state\n";
                idle();
                break;
        }
    }
}

void IRHandler::waiting() {
    for (;;) {

        RTOS::event e = wait(IRClock);

        while (e != IRClock) {
            release();
        }



        if (IRSensor.getState()) {

            indexCounter = 0;
            signalCounter = 1;

            msTimer.set(8 MS);
            state = Receiving;
            return;
        }
    }
}

void IRHandler::receiving() {
    //int i = 0, j=0;
    for (;;) {

        RTOS::event e = wait(msTimer + IRClock);
        if (e == msTimer) {
            state = Waiting;
            std::cout << "Time-out occured! \n";
            return;

        } else if (e == IRClock) {
            //std::cout << "Clock fired! \n";
            //j++;

            if (IRSensor.getState()) {
                signalCounter++;
                lowCounter = 0;


            } else {
                lowCounter++;
                if (lowCounter == 1) {
                    if (signalCounter >= 5) {

                        bits[indexCounter++] = 1;
                        signalCounter = 0;
                        msTimer.set(10 S);
                    } else if (signalCounter >= 2 && signalCounter <= 4) { //possible problem
                        bits[indexCounter++] = 0;
                        signalCounter = 0; 
                        msTimer.set(10 S);

                    }
                }
                if (indexCounter > 14 || lowCounter > 20) {
                    
                    msTimer.cancel();
                    process();
                    state = Waiting;
                    return;
                  


                     

                    


                }
                
            }

        }

    }

/*
    std::cout << "\n";
                        int i;
                        for (i = 0; i < 15; i++) {
                            if ((i - 1) % 5 == 4) {
                                std::cout << "-";
                            }
                            std::cout << bits[i];
                        }
                        std::cout << "\n";
 */


}

void IRHandler::process() {
    sleep(1 S);
    std::cout << "\n";
                        int i;
                        for (i = 0; i < 15; i++) {
                            if ((i - 1) % 5 == 4) {
                                std::cout << "-";
                            }
                            std::cout << bits[i];
                        }
                        std::cout << "\n";
    unsigned int player = bits[0] << 4 | bits[1] << 3 | bits[2] << 2 | bits[3] << 1 | bits[4];
    unsigned int weapon = bits[5] << 4 | bits[6] << 3 | bits[7] << 2 | bits[8] << 1 | bits[9];
    unsigned int exor = bits[10] << 4 || bits[11] << 3 || bits[12] << 2 || bits[13] << 1 || bits[14];
    if (!player && !weapon) {
        listener->startSignalReceived();
        state = Waiting;
        return;
    } else if (!player && weapon == 1) {
        listener->logSignalReceived();
        state = Waiting;
        return;
    } else {
        std::cout << "\nPlayerID: " << player
                << " WeaponID: " << weapon << "\n";
        shooter.playerID = player;
        shooter.weaponID = weapon;
        state = Idle;
        return;
    }

}

void IRHandler::idle() {
    listener->hitSignalReceived(shooter);
    msTimer.set(5 S);
    RTOS::event e = wait(msTimer);
    while (e != msTimer) {
        release();
    }
    state = Waiting;
    return;
}